﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyLogPC.PLCs
{
    //数组变化事件帮助类
    public class ArrayChangedEventArgs<T> : EventArgs
    {
        /// <summary>
        /// 获取当前项目的零基索引。
        /// </summary>
        public int Index { get; }
        /// <summary>
        /// 获取当前项目的值。
        /// </summary>
        public T NewValue { get; }

        //构造函数
        public ArrayChangedEventArgs(int index, T newValue)
        {
            Index = index;
            NewValue = newValue;
        }

    }

    public class ObservableArray<T>
    {
        private T[] _array;
        public event EventHandler<ArrayChangedEventArgs<T>> ElementChanged;

        //获取数组的长度
        public int Length => _array.Length;
        public ObservableArray(int size)
        {
            _array = new T[size];
        }
        /// <summary>
        ///  索引器
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public T this[int index]
        {
            get { if (index < 0 || index >= _array.Length) throw new IndexOutOfRangeException(); return _array[index]; }//如果索引越界则抛出异常
            set
            {
                if (index < 0 || index >= _array.Length) throw new IndexOutOfRangeException(); //如果索引越界则抛出异常
                                                                                               // Replace the problematic line in the ObservableArray<T> class
                if (!EqualityComparer<T>.Default.Equals(_array[index], value)) //如果新值与旧值不同，则触发事件
                {
                    _array[index] = value;
                    OnElementChanged(new ArrayChangedEventArgs<T>(index, value)); //触发事件
                }

            }
        }
        /// <summary>
        /// 设置整个数组的值
        /// </summary>
        /// <param name="newArray"></param>
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="ArgumentException"></exception>
        public void SetArray(T[] newArray)
        {
            if (newArray == null) throw new ArgumentNullException(nameof(newArray));
            if (newArray.Length != this.Length) throw new ArgumentException("新数组长度必须与旧数组长度一致", nameof(newArray));
            for (int i = 0; i < this.Length; i++)
            {
                if (!object.Equals(this[i], newArray[i]))
                {
                    this[i] = newArray[i];
                }
            }
        }

        /// <summary>
        /// 触发事件的函数
        /// </summary>
        /// <param name="e"></param>
        public virtual void OnElementChanged(ArrayChangedEventArgs<T> e)
        {
            ElementChanged?.Invoke(this, e);
        }
    }
}
